﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock;

namespace PrimaryStudentPainProgram
{
    public partial class TestForm : Form
    {
        ParentForm parentForm;

        Timer timer =new Timer();
        int counter;

        int puzzleNumber = 1;

        List<Node> nodeList = new List<Node>();
        int answer=0;
        bool toNext=false;

        public TestForm(ParentForm parentForm)
        {
            InitializeComponent();
            this.parentForm = parentForm;
            this.WindowState = FormWindowState.Maximized;

            timer.Interval = 1000;
            timer.Start();
            timer.Tick += timer_tick1;
            timer.Tick += timer_tick2;
            init();
        }

        private void init()
        {
            counter = 0;
            nodeList.Clear();
            puzzlestr = "";
            this.textBoxAnswer.Text = "" ;
            this.textBoxPuzzle.Text = puzzle();
            this.labelTimer.Text = "倒计时" + parentForm.INTERVAL;
            answer = calculate(nodeList[0]);
        }

        private void timer_tick1(object sender, EventArgs eventArgs)
        {
            counter++;
            int time = parentForm.INTERVAL - counter;
            this.labelTimer.Text = "倒计时" + time;
            if (time <= 0) 
                this.textBoxAnswer.Text = "超时";
            if (time <= -3)
            {
                parentForm.wrongList.Add(new FixPair(
                    this.textBoxPuzzle.Text,
                    true,
                    0, answer));
                this.labelTimer.Text = "倒计时" + parentForm.INTERVAL;
                init();
            }
        }

        int waiter = 0;
        private void timer_tick2(object sender, EventArgs eventArgs)
        {
            if (toNext)
                waiter++;
            if (waiter == 2)
            {
                waiter = 0;
                toNext = false;
                init();
            }
        }

        private void buttonNext_Click(object sender, EventArgs e)
        {
            check();
            puzzleNumber++;
            if(puzzleNumber>parentForm.MAX_NUM)
            {
                parentForm.finish(this);
            }
            toNext = true;
        }

        private string puzzlestr="";
       
        private string puzzle()
        {
            Random r = new Random();
            int num_operator = r.Next(4) + 2;

            nodeList.Add(new Node(getOperator(r.Next(4))));
            int _operator = 1;
            for(int i = 0; i < nodeList.Count; i++)
            {
                if (nodeList[i] == null)
                    break;

                int L_Or_R_is_Operator = r.Next(2);
                int Other_is_Operator = r.Next(2);
                if (_operator <= num_operator)
                {
                    if (L_Or_R_is_Operator == 0)
                        nodeList[i].lchild = new Node(getOperator(r.Next(4)));
                    else
                        nodeList[i].rchild = new Node(getOperator(r.Next(4)));
                    _operator++;
                }

                if (_operator >= num_operator || Other_is_Operator == 0)
                {
                    if (L_Or_R_is_Operator == 0)
                        nodeList[i].rchild = new Node(r.Next(parentForm.MAX_NUM).ToString());
                    else
                        nodeList[i].lchild = new Node(r.Next(parentForm.MAX_NUM).ToString());
                }
                else
                {
                    if (L_Or_R_is_Operator == 0)
                        nodeList[i].rchild = new Node(getOperator(r.Next(4)));
                    else
                        nodeList[i].lchild = new Node(getOperator(r.Next(4)));
                    _operator++;
                }

                Node nl = nodeList[i].lchild;
                Node nr = nodeList[i].rchild;
                if (nl != null && nl.isOperator)
                    nodeList.Add(nl);
                if (nr != null && nr.isOperator)
                    nodeList.Add(nr);
            }

            for(int i = 0; i < nodeList.Count; i++)
            {
                if (nodeList[i] == null)
                    break;
                if (nodeList[i].isOperator == true)
                {
                    if (nodeList[i].lchild == null)
                        nodeList[i].lchild = new Node(r.Next(parentForm.MAX_NUM).ToString());
                    if(nodeList[i].rchild==null)
                        nodeList[i].rchild = new Node(r.Next(parentForm.MAX_NUM).ToString());
                }
            }

            Node n = nodeList[0];
            outputTree(nodeList[0]);
            return puzzlestr.Substring(1,puzzlestr.Length-2)+'=';
        }

        private int calculate(Node root)
        {
            if (root == null)
            {
                return 0;
            }
            if (!root.isOperator)
                return int.Parse(root.value);
            else
                switch(root.value)
                {
                    case "+":return calculate(root.lchild) + calculate(root.rchild);
                    case "-":return calculate(root.lchild) - calculate(root.rchild);
                    case "*":return calculate(root.lchild) * calculate(root.rchild);
                    case "/":return calculate(root.lchild) / calculate(root.rchild);
                }
            return 0;
        }

        private void check()
        {
            try
            {
                int input=int.Parse(this.textBoxAnswer.Text);
                if (input == answer)
                    this.textBoxAnswer.Text = "正确";
                else if (input != answer 
                    || this.textBoxAnswer.Text.Length == 0) 
                {
                    this.textBoxAnswer.Text = "错误";
                    parentForm.wrongList.Add(new FixPair(
                        this.textBoxPuzzle.Text,
                        false,
                        input,
                        answer)) ;
                }
            }catch (Exception)
            {
                this.textBoxAnswer.Text = "输入错误";
            }
        }
        
        private void outputTree(Node n)
        {
            if (n == null)
                return;
            if (n.isOperator)
                puzzlestr += "(";
            outputTree(n.lchild);
            puzzlestr += n.value;
            outputTree(n.rchild);
            if (n.isOperator) 
                puzzlestr += ")";
        }
        
        private string getOperator(int index)
        {
            switch (index)
            {
                case 0:return "+";
                case 1:return "-";
                case 2:return "*";
                //case 3:return "/";
                default:return "*";
            }
        }
    }

    class Node
    {
        public Node lchild;
        public Node rchild;
        public string value;
        public bool isOperator=false;

        public Node(string v)
        {
            this.value = v;
            this.lchild = null;
            this.rchild = null;
            if (v.Equals("+") || v.Equals("-") || v.Equals("*") || v.Equals("/"))
                isOperator = true;
        }
    }

}
